#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

/* memory.c */
#define MEMMAN_FREES 4096  // (4+4)*4096 = 32768 = 32KB
#define MEMMAN_ADDR 0x003c0000
// 可用信息
struct FREEINFO {
    uint32_t addr;
    uint32_t size;
};

// 内存管理
struct MEMMAN {
    int32_t frees;                       // free信息表的占用总数
    int32_t maxfrees;                    // 用于观察可用状况：frees的最大值
    int32_t lostsize;                    // 释放失败的内存的大小总和
    int32_t losts;                       // 释放失败的次数
    struct FREEINFO free[MEMMAN_FREES];  // 所有free信息表
};
/**
 * @brief 初始化内存结构体
 *
 * @param man
 */
void memman_init(struct MEMMAN *man);
/**
 * @brief 释放一块内存到内存管理器
 *
 * @param man
 * @param addr
 * @param size
 * @return int
 */
int memman_free(struct MEMMAN *man, uint32_t addr, uint32_t size);
/**
 * @brief 申请一块内存
 *
 * @param man
 * @param size
 * @return uint32_t
 */
uint32_t memman_alloc(struct MEMMAN *man, uint32_t size);
/**
 * @brief 计算内存大小
 *
 * @param start
 * @param end
 * @return uint32_t
 */
uint32_t memtest(unsigned int start, unsigned int end);
/**
 * @brief 获取剩余内存大小
 *
 * @param man
 * @return uint32_t
 */
uint32_t memman_total(struct MEMMAN *man);
/**
 * @brief 申请内存，按照4K对齐向上取整
 *
 * @param man
 * @param size 输入的size会按照4K向上取整
 * @return uint32_t 首地址
 */
uint32_t memman_alloc_4k(struct MEMMAN *man, uint32_t size);
/**
 * @brief 按照4K对齐释放内存
 *
 * @param man
 * @param addr
 * @param size
 * @return int 成功返回0，失败返回-1
 */
int memman_free_4k(struct MEMMAN *man, uint32_t addr, uint32_t size);

#ifdef __cplusplus
}
#endif
